home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 176-200 / disk_190 / nethack / twee.zoo / makemon.c < prev    next >
C/C++ Source or Header  |  1988-07-25  |  10KB  |  414 lines

  1. /*    SCCS Id: @(#)makemon.c  2.3     87/12/12
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  
  4. #include    "hack.h"
  5. extern char fut_geno[];
  6. extern char *index();
  7. extern struct obj *mkobj_at(), *mksobj(), *mkobj();
  8. struct monst zeromonst;
  9. extern boolean in_mklev;
  10.  
  11. #ifdef HARD        /* used in hell for bigger, badder demons! */
  12.  
  13. struct permonst d_lord     = { "demon lord",      '&',12,13,-5,50,1,5,0 },
  14.         d_prince = { "demon prince",    '&',14,14,-6,70,1,6,0 };
  15. #endif
  16. #ifdef KJSMODS
  17. # ifdef KOPS
  18. struct permonst kobold = { "kobold",'K',1,6,7,0,1,4,0 };
  19. # endif
  20. # ifdef ROCKMOLE
  21. struct permonst giant_rat = { "giant rat",'r',0,12,7,0,1,3,0 };
  22. # endif
  23. #endif /* KJSMODS /**/
  24.  
  25. struct permonst grey_dragon   = { "grey dragon",  'D',10,9,-1,20,3,8,0 };
  26. struct permonst red_dragon    = { "red dragon",   'D',10,9,-1,20,3,8,0 };
  27. struct permonst orange_dragon = { "orange dragon",'D',10,9,-1,20,3,8,0 };
  28. struct permonst white_dragon  = { "white dragon", 'D',10,9,-1,20,3,8,0 };
  29. struct permonst black_dragon  = { "black dragon", 'D',10,9,-1,20,3,8,0 };
  30. struct permonst blue_dragon   = { "blue dragon",  'D',10,9,-1,20,3,8,0 };
  31. struct permonst green_dragon  = { "green dragon", 'D',10,9,-1,20,3,8,0 };
  32. struct permonst yellow_dragon = { "yellow dragon",'D',10,9,-1,20,3,8,0 };
  33. extern struct permonst pm_gremlin;
  34.  
  35. /*
  36.  * called with [x,y] = coordinates;
  37.  *    [0,0] means anyplace
  38.  *    [u.ux,u.uy] means: call mnexto (if !in_mklev)
  39.  *
  40.  *    In case we make an Orc or killer bee, we make an entire horde
  41.  *    (swarm); note that in this case we return only one of them
  42.  *    (the one at [x,y]).
  43.  */
  44. struct monst *
  45. makemon(ptr,x,y)
  46. register struct permonst *ptr;
  47. {
  48.     register struct monst *mtmp;
  49.     register nleft, deep, ct;
  50.     boolean anything = (!ptr);
  51.     int zlevel = dlevel;
  52. #ifdef BVH
  53.     if(has_amulet()) zlevel = MAXLEVEL;
  54. #endif
  55.     /* if a monster already exists at the position, return */
  56.     if(x != 0 || y != 0) if(m_at(x,y)) return((struct monst *) 0);
  57.     if(ptr){
  58.         /* if you are to make a specific monster and it has
  59.            already been genocided, return */
  60.         if(index(fut_geno, ptr->mlet)) return((struct monst *) 0);
  61.     } else {
  62.         /* make a random (common) monster. */
  63.         nleft = CMNUM - strlen(fut_geno);
  64.         if(index(fut_geno, 'm')) nleft++;  /* only 1 minotaur */
  65.         if(index(fut_geno, '@')) nleft++;
  66.         if(nleft <= 0)
  67.             return((struct monst *) 0); /* no more monsters! */
  68.  
  69.         /* determine the strongest monster to make. */
  70. #ifdef ROCKMOLE
  71.         deep = rn2(nleft*zlevel/24 + 6);
  72. #else
  73.         deep = rn2(nleft*zlevel/24 + 7);
  74. #endif
  75.         if(deep < zlevel - 4) deep = rn2(nleft*zlevel/24 + 12);
  76.         /* if deep is greater than the number of monsters left
  77.            to create, set deep to a random number between half
  78.            the number left and the number left. */
  79.         if(deep >= nleft) deep = rn1(nleft - nleft/2, nleft/2);
  80.  
  81.         for(ct = 0 ; ct < CMNUM ; ct++){
  82.             ptr = &mons[ct];
  83.             if(index(fut_geno, ptr->mlet)) continue;
  84. #ifdef KOPS
  85.             if(ptr->mlet == 'K') {
  86. # ifdef KJSMODS
  87.                 /* since this is a random monster, make
  88.                    a Kobold instead of a Kop. */
  89.                 ptr = &kobold;
  90. # else
  91.                 deep--;
  92. # endif
  93.                 continue;
  94.             }
  95. #endif /* KOPS /**/
  96.             if(deep-- <= 0) goto gotmon;
  97.         }
  98.         /* this can happen if you are deep in the dungeon and
  99.            mostly weak monsters have been genocided. */
  100.         return((struct monst *) 0);
  101.     }
  102. gotmon:
  103. /* #if defined(KJSMODS) && defined(ROCKMOLE) */
  104. #ifdef KJSMODS
  105. # ifdef ROCKMOLE
  106.     /* make a giant rat */
  107.     if((zlevel < 4 && ptr->mlet == 'r')
  108.        || (zlevel == 1 && (ptr->mlet == 'h' || ptr->mlet == 'i'))
  109.        || (zlevel == 2 && (ptr->mlet == 'o' || ptr->mlet == 'y'))
  110.     ) ptr = &giant_rat;
  111. # endif
  112. #endif
  113.     mtmp = newmonst(ptr->pxlth);
  114.     *mtmp = zeromonst;    /* clear all entries in structure */
  115.     for(ct = 0; ct < ptr->pxlth; ct++)
  116.         ((char *) &(mtmp->mextra[0]))[ct] = 0;
  117.     mtmp->nmon = fmon;
  118.     fmon = mtmp;
  119.     mtmp->m_id = flags.ident++;
  120.     mtmp->data = ptr;
  121.     mtmp->mxlth = ptr->pxlth;
  122.     if(ptr->mlet == 'D') mtmp->mhpmax = mtmp->mhp = 80;
  123.     else if(!ptr->mlevel) mtmp->mhpmax = mtmp->mhp = rnd(4);
  124.     else mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8);
  125.     mtmp->mx = x;
  126.     mtmp->my = y;
  127.     mtmp->mcansee = 1;
  128.     if(ptr->mlet == 'D') {
  129.         mtmp->dragon = rn2(8);
  130.         switch(mtmp->dragon) {
  131.             case 0: mtmp->data = &grey_dragon;    break;
  132.             case 1: mtmp->data = &red_dragon;    break;
  133.             case 2: mtmp->data = &orange_dragon;    break;
  134.             case 3: mtmp->data = &white_dragon;    break;
  135.             case 4: mtmp->data = &black_dragon;    break;
  136.             case 5: mtmp->data = &blue_dragon;    break;
  137.             case 6: mtmp->data = &green_dragon;    break;
  138.             case 7: mtmp->data = &yellow_dragon;    break;
  139.         }
  140.     }
  141.     /* if gnome, make a gremlin or if gremlin make sure it stays gremlin */
  142.     if((ptr->mlet == 'G' && zlevel >= 10 && rn2(4)) ||
  143.         !strcmp(ptr->mname, "gremlin")) {
  144.         ptr = PM_GREMLIN;
  145.         mtmp->data = PM_GREMLIN;
  146.         mtmp->isgremlin = 1;
  147.     }
  148.     if(ptr->mlet == 'M'){
  149.         mtmp->mimic = 1;
  150.         mtmp->mappearance = ']';
  151.     }
  152.     if(!in_mklev) {
  153.         if(x == u.ux && y == u.uy && ptr->mlet != ' ')
  154.             mnexto(mtmp);
  155.         if(x == 0 && y == 0)
  156.             rloc(mtmp);
  157.     }
  158.     if(ptr->mlet == 's' || ptr->mlet == 'S') {
  159.         mtmp->mhide = mtmp->mundetected = 1;
  160.         if(in_mklev)
  161.         if(mtmp->mx && mtmp->my)
  162.             (void) mkobj_at(0, mtmp->mx, mtmp->my);
  163.     }
  164.     if(ptr->mlet == ':') {
  165. #ifdef DGKMOD
  166.         /* If you're protected with a ring, don't create
  167.          * any shape-changing chameleons -dgk
  168.          */
  169.         if (Protection_from_shape_changers)
  170.             mtmp->cham = 0;
  171.         else {
  172.             mtmp->cham = 1;
  173.             (void) newcham(mtmp,
  174. # ifndef RPH
  175.                 &mons[zlevel+14+rn2(CMNUM-14-zlevel)]);
  176. # else
  177.                 (struct permonst *)0);
  178. # endif
  179.         }
  180. #else
  181.         mtmp->cham = 1;
  182.         (void) newcham (mtmp,
  183. # ifndef RPH
  184.                 &mons[zlevel+14+rn2(CMNUM-14-zlevel)]);
  185. # else
  186.                 Null(permonst));
  187. # endif
  188. #endif
  189.     }
  190.     if(ptr->mlet == 'I' || ptr->mlet == ';')
  191.         mtmp->minvis = 1;
  192.     if(ptr->mlet == 'L' || ptr->mlet == 'N'
  193.         || (in_mklev && index("&w;", ptr->mlet) && rn2(5))
  194.     ) mtmp->msleep = 1;
  195. #ifdef HARD
  196.     if(ptr->mlet == '&' && (Inhell || u.udemigod)) {
  197.  
  198.         if(!rn2(3 + !Inhell + !u.udemigod)) {
  199.             if (rn2(3 + Inhell)) mtmp->data = &d_lord;
  200.             else  {
  201.             mtmp->data = &d_prince;
  202.             mtmp->mpeaceful = 1;
  203.             mtmp->minvis = 1;
  204.             }
  205.         }
  206. #ifdef RPH
  207.         if(uwep)
  208.             if(!strcmp(ONAME(uwep), "Excalibur"))
  209.             mtmp->mpeaceful = mtmp->mtame = 0;
  210. #endif
  211.     }
  212. #endif /* HARD /**/
  213. #ifndef NOWORM
  214.     if(ptr->mlet == 'w' && getwn(mtmp))  initworm(mtmp);
  215. #endif
  216.  
  217.     if(anything)
  218.         if(ptr->mlet == 'O' || ptr->mlet == 'k'
  219. #ifdef SAC
  220.            || ptr->mlet == '3'
  221. #endif /* SAC /**/
  222.            || (ptr->mlet == 'G' && mtmp->isgremlin)
  223.                   ) {
  224.  
  225.         coord mm;
  226.         register int cnt = rnd(10);
  227.         mm.x = x;
  228.         mm.y = y;
  229.         while(cnt--) {
  230.             enexto(&mm, mm.x, mm.y);
  231.             (void) makemon(ptr, mm.x, mm.y);
  232.         }
  233.     }
  234. #ifdef DGKMOD
  235.     m_initinv(mtmp);
  236. #endif
  237.     return(mtmp);
  238. }
  239.  
  240. #ifdef DGKMOD
  241. /* Give some monsters an initial inventory to use */
  242. m_initinv(mtmp)
  243. struct monst *mtmp;
  244. {
  245.     struct obj *otmp;
  246.  
  247.     switch (mtmp->data->mlet) {
  248. # ifdef KAA
  249.     case '9':
  250.         if (rn2(2)) {
  251.             otmp = mksobj(ENORMOUS_ROCK);
  252.             mpickobj(mtmp, otmp);
  253.         }
  254. # endif
  255. # ifdef SAC
  256.     case '3':                       /* Outfit the troops */
  257.         if (!rn2(5)) {
  258.             otmp = mksobj(HELMET);
  259.             mpickobj(mtmp, otmp); }
  260.         if (!rn2(5)) {
  261.             otmp = mksobj(CHAIN_MAIL);
  262.             mpickobj(mtmp, otmp); }
  263.         if (!rn2(4)) {
  264.             otmp = mksobj(DAGGER);
  265.             mpickobj(mtmp, otmp); }
  266.         if (!rn2(7)) {
  267.             otmp = mksobj(SPEAR);
  268.             mpickobj(mtmp, otmp); }
  269.         if (!rn2(3)) {
  270.             otmp = mksobj(K_RATION);
  271.             mpickobj(mtmp, otmp); }
  272.         if (!rn2(2)) {
  273.             otmp = mksobj(C_RATION);
  274.             mpickobj(mtmp, otmp); }
  275. # endif /* SAC /**/
  276. # ifdef KOPS
  277.     case 'K':               /* create Keystone Kops with cream pies to
  278.                  * throw. As suggested by KAA.       [MRS]
  279.                  */
  280.         if (!rn2(4)
  281. #  ifdef KJSMODS
  282.             && !strcmp(mtmp->data->mname, "Keystone Kop")
  283. #  endif
  284.                                 ) {
  285.             otmp = mksobj(CREAM_PIE);
  286.             otmp->quan = 2 + rnd(2);
  287.             otmp->owt = weight(otmp);
  288.             mpickobj(mtmp, otmp);
  289.         }
  290.         break;
  291.     case 'O':
  292. # else
  293.     case 'K':
  294. # endif
  295.         if (!rn2(4)) {
  296.             otmp = mksobj(DART);
  297.             otmp->quan = 2 + rnd(12);
  298.             otmp->owt = weight(otmp);
  299.             mpickobj(mtmp, otmp);
  300.         }
  301.         break;
  302.  
  303.     case 'C':
  304.         if (rn2(2)) {
  305.             otmp = mksobj(CROSSBOW);
  306.             otmp->cursed = rn2(2);
  307.             mpickobj(mtmp, otmp);
  308.             otmp = mksobj(CROSSBOW_BOLT);
  309.             otmp->quan = 2 + rnd(12);
  310.             otmp->owt = weight(otmp);
  311.             mpickobj(mtmp, otmp);
  312.         }
  313.         break;
  314.     default:
  315.         break;
  316.     }
  317. }
  318. #endif
  319.  
  320. enexto(cc, xx,yy)
  321. coord    *cc;
  322. register xchar xx,yy;
  323. {
  324.     register xchar x,y;
  325.     coord foo[15], *tfoo;
  326.     int range, i;
  327.  
  328.     tfoo = foo;
  329.     range = 1;
  330.     do {    /* full kludge action. */
  331.         for(x = xx-range; x <= xx+range; x++)
  332.             if(goodpos(x, yy-range)) {
  333.                 tfoo->x = x;
  334.                 (tfoo++)->y = yy-range;
  335.                 if(tfoo == &foo[15]) goto foofull;
  336.             }
  337.         for(x = xx-range; x <= xx+range; x++)
  338.             if(goodpos(x,yy+range)) {
  339.                 tfoo->x = x;
  340.                 (tfoo++)->y = yy+range;
  341.                 if(tfoo == &foo[15]) goto foofull;
  342.             }
  343.         for(y = yy+1-range; y < yy+range; y++)
  344.             if(goodpos(xx-range,y)) {
  345.                 tfoo->x = xx-range;
  346.                 (tfoo++)->y = y;
  347.                 if(tfoo == &foo[15]) goto foofull;
  348.             }
  349.         for(y = yy+1-range; y < yy+range; y++)
  350.             if(goodpos(xx+range,y)) {
  351.                 tfoo->x = xx+range;
  352.                 (tfoo++)->y = y;
  353.                 if(tfoo == &foo[15]) goto foofull;
  354.             }
  355.         range++;
  356.     } while(tfoo == foo);
  357. foofull:
  358.     i = rn2(tfoo - foo);
  359.     cc->x = foo[i].x;
  360.     cc->y = foo[i].y;
  361.     return(0);
  362. }
  363.  
  364. goodpos(x,y)    /* used only in mnexto and rloc */
  365. {
  366.     return(
  367.     ! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 ||
  368.        m_at(x,y) || !ACCESSIBLE(RM_TYP(levl[x][y]))
  369.        || (x == u.ux && y == u.uy)
  370.        || sobj_at(ENORMOUS_ROCK, x, y)
  371.     ));
  372. }
  373.  
  374. rloc(mtmp)
  375. struct monst *mtmp;
  376. {
  377.     register tx,ty;
  378.     register char ch = mtmp->data->mlet;
  379.  
  380. #ifndef NOWORM
  381.     if(ch == 'w' && mtmp->mx) return;       /* do not relocate worms */
  382. #endif
  383.     do {
  384.         tx = rn1(COLNO-3,2);
  385.         ty = rn2(ROWNO);
  386.     } while(!goodpos(tx,ty));
  387.     mtmp->mx = tx;
  388.     mtmp->my = ty;
  389.     if(u.ustuck == mtmp){
  390.         if(u.uswallow) {
  391.             u.ux = tx;
  392.             u.uy = ty;
  393.             docrt();
  394.         } else    u.ustuck = 0;
  395.     }
  396.     pmon(mtmp);
  397. }
  398.  
  399. struct monst *
  400. mkmon_at(let,x,y)
  401. char let;
  402. register int x,y;
  403. {
  404.     register int ct;
  405.     register struct permonst *ptr;
  406.  
  407.     for(ct = 0; ct < CMNUM; ct++) {
  408.         ptr = &mons[ct];
  409.         if(ptr->mlet == let)
  410.             return(makemon(ptr,x,y));
  411.     }
  412.     return((struct monst *)0);
  413. }
  414.